
import {
  Injectable
} from '@angular/core';

import {
  Database,
  Store,
} from '../../libs/smoke-database';


export interface IEntity {
  getId(): number|null;
}

export type QueryFunction = (obj: any, index: number) => boolean;

export class BaseDataService  {


  private DATABASE_NAME = 'mzzckj';
  protected ENTITY_NAME: string;
  protected COLLECTION = ['order','user','home','account','charg','complain','chargstation','question','help','aboutus','mtc', 'deviceInfo', 'cCPeriod'];
  version = 1;
  protected database: Database;

  constructor() {
    this.onInit();
  }

  protected onInit() {
    this.database = new Database(this.DATABASE_NAME, this.COLLECTION);
  }

  public async save( entity: any): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      if ('key' in entity) {
          this.database.store(this.ENTITY_NAME).get(entity.key)
          .then((data) => {
            if (data == null) {
              entity.key = Database.createKey();
              this.database.store(this.ENTITY_NAME)
                .insert([entity])
                  .then((result) => {
                    this.resolveResult(result);
                    resolve(entity.key);
                  })
                  .catch((result) => {
                    this.resolveResult(result);
                    resolve(entity.key);
                  });
            } else {
              this.database.store(this.ENTITY_NAME)
                .update([entity])
                .then((result) => {
                  this.resolveResult(result);
                  resolve(entity.key);
                })
                .catch((result) => {
                  this.resolveResult(result);
                  resolve(entity.key);
                });
            }
          });
      } else {
        entity.key = Database.createKey();
              this.database.store(this.ENTITY_NAME)
                .insert([entity])
                  .then((result) => {
                    this.resolveResult(result);
                    resolve(entity.key);
                  })
                  .catch((result) => {
                    this.resolveResult(result);
                    resolve(entity.key);
                  });
      }
    });
  }

  private resolveResult(result: any) {
    console.log(result);
  }

  public async find(queryFunction: QueryFunction): Promise<any[]> {
      return this.database.store(this.ENTITY_NAME).query().where(queryFunction).collect();
  }

  public async findAsc<U>(queryFunction: QueryFunction, comp: (left: any, right: any) => number): Promise<any[]> {
    return this.database.store(this.ENTITY_NAME).query().where(queryFunction).orderCmpBy(comp).collect();
  }

  public async findDesc<U>(queryFunction: QueryFunction, comp: (left: any, right: any) => number): Promise<any[]> {
    return this.database.store(this.ENTITY_NAME).query().where(queryFunction).orderCmpByDescending(comp).collect();
  }

  public async delete(queryFunction: QueryFunction): Promise<number> {
    return new Promise<number>((resolve, reject) => {
      const _store = this.database.store(this.ENTITY_NAME);
      _store.query().where(queryFunction).collect()
        .then(function(datas){
          const _datas = datas;
          _store.delete(datas).then(() => {
            resolve(_datas.length);
          });
        });
    });
  }

  public async deleteAll(): Promise<number> {
    return await this.delete(() => {
       return true;
    });
  }
}
